/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bef.bizentity.common;

import com.inspur.edp.bef.bizentity.GspBizEntityObject;
import com.inspur.edp.bef.bizentity.beenum.BETriggerTimePointType;
import com.inspur.edp.bef.bizentity.beenum.RequestNodeTriggerType;
import com.inspur.edp.bef.bizentity.collection.DtmElementCollection;
import com.inspur.edp.bef.bizentity.operation.BizCommonDetermination;
import com.inspur.edp.bef.bizentity.operation.BizCommonValdation;
import com.inspur.edp.bef.bizentity.operation.BizOperation;
import com.inspur.edp.bef.bizentity.operation.Determination;
import com.inspur.edp.bef.bizentity.operation.Validation;
import com.inspur.edp.bef.bizentity.operation.collection.DeterminationCollection;
import com.inspur.edp.bef.bizentity.operation.collection.ValidationCollection;
import com.inspur.edp.cef.designtime.api.collection.CommonDtmCollection;
import com.inspur.edp.cef.designtime.api.collection.CommonValCollection;
import com.inspur.edp.cef.designtime.api.collection.ValElementCollection;
import com.inspur.edp.cef.designtime.api.json.CefNames;
import com.inspur.edp.cef.designtime.api.operation.*;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

/**
 * bizOp=>commonOp转换
 */
public class OperationConvertUtils {

  /**
   * 转换联动计算列表
   *
   * @param dtms 联动计算集合
   * @param type 触发时机
   * @return
   */
  public static CommonDtmCollection convertToCommonDtms(DeterminationCollection dtms,
      BETriggerTimePointType type) {
    CommonDtmCollection cDtms = new CommonDtmCollection();
    for (BizOperation op : dtms) {
      Determination dtm = (Determination) op;
      if (dtm.getTriggerTimePointType().contains(type)) {
        cDtms.add(convertToCommonDtm(dtm));
      }
    }
    return cDtms;
  }

  public static DeterminationCollection convertToDtmCollection(CommonDtmCollection dtms,
      BETriggerTimePointType type) {
    DeterminationCollection dtmCollection = new DeterminationCollection();
    for (CommonDetermination op : dtms) {
      BizCommonDetermination commonDetermination = (BizCommonDetermination) op;
      dtmCollection.add(convertToDetermination(commonDetermination, type));
    }
    return dtmCollection;
  }

  /**
   * 转换校验规则列表
   *
   * @param vals
   * @return
   */
  public static CommonValCollection convertToCommonValidations(ValidationCollection vals,
      BETriggerTimePointType type) {
    CommonValCollection cVals = new CommonValCollection();
    for (BizOperation op : vals) {
      Validation val = (Validation) op;
      if (val.getValidationTriggerPoints().containsKey(type)
          && val.getValidationTriggerPoints().get(type).size() > 0) {
        cVals.add(convertToCommonValidation(val, type));
      }
    }
    return cVals;
  }

  // region 私有方法
  public static CommonDetermination convertToCommonDtm(Determination dtm) {
    BizCommonDetermination cDtm = new BizCommonDetermination();
    convertToCommonOperation(cDtm, dtm);
    cDtm.setParameterCollection(dtm.getParameterCollection());
    cDtm.setRunOnce(dtm.getRunOnce());
    cDtm.setGetExecutingDataStatus(getExecutingDataStatus(dtm.getRequestNodeTriggerType()));
    if (dtm.getRequestElements().size() > 0) {
      for (String item : dtm.getRequestElements()) {
        cDtm.getRequestElements().add(item);
      }
    }
    if (dtm.getRequestChildElements() != null && dtm.getRequestChildElements().size() > 0) {
      HashMap<String, com.inspur.edp.cef.designtime.api.collection.DtmElementCollection> childEls = new HashMap<>();
      for (Map.Entry<String, DtmElementCollection> item : dtm.getRequestChildElements()
          .entrySet()) {
        com.inspur.edp.cef.designtime.api.collection.DtmElementCollection collection =
            new com.inspur.edp.cef.designtime.api.collection.DtmElementCollection();
        if (item.getValue() != null) {
          for (String s : item.getValue()) {
            collection.add(s);
          }
        }
        childEls.put(item.getKey(), collection);
      }
      cDtm.setRequestChildElements(childEls);
//			cDtm.setChildTriggerInfo(hashMap);
    }
    return cDtm;
  }

  public static Determination convertToDtm(CommonDetermination common,
      String triggerTimePointType, GspBizEntityObject parent) {
    Determination operation = new Determination();
    operation.setID(common.getID());
    operation.setCode(common.getCode());
    operation.setName(common.getName());
    operation.setDescription(common.getDescription());
    operation.setComponentId(common.getComponentId());
    operation.setComponentName(common.getComponentName());
    operation.setComponentPkgName(common.getComponentPkgName());
    operation.setOwner(parent);
    operation.setTriggerTimePointType(EnumSet.of(convert2TriggerTimePointType(
        triggerTimePointType, common.getTriggerPointType())));
    operation.setIsGenerateComponent(common.getIsGenerateComponent());
    return operation;
  }

  public static Validation convertToVal(CommonValidation common,
      String triggerTimePointType, GspBizEntityObject parent) {
    Validation operation = new Validation();
    operation.setID(common.getID());
    operation.setCode(common.getCode());
    operation.setName(common.getName());
    operation.setDescription(common.getDescription());
    operation.setComponentId(common.getComponentId());
    operation.setComponentName(common.getComponentName());
    operation.setComponentPkgName(common.getComponentPkgName());
    operation.setOwner(parent);
    operation.getValidationTriggerPoints().put(
        convert2TriggerTimePointType(triggerTimePointType,
            common.getTriggerPointType()), EnumSet.of(RequestNodeTriggerType.Created));
    operation.setIsGenerateComponent(common.getIsGenerateComponent());
    return operation;
  }

  public static Determination convertToDetermination(BizCommonDetermination commonDetermination,
      BETriggerTimePointType type) {
    Determination dtm = new Determination();
    dtm.setID(commonDetermination.getID());
    dtm.setCode(commonDetermination.getCode());
    dtm.setName(commonDetermination.getName());
    dtm.setDescription(commonDetermination.getDescription());
    dtm.setComponentId(commonDetermination.getComponentId());
    dtm.setComponentName(commonDetermination.getComponentName());
    dtm.setComponentPkgName(commonDetermination.getComponentPkgName());
    dtm.setParameterCollection(commonDetermination.getParameterCollection());
    dtm.setRunOnce(dtm.getRunOnce());
    if (commonDetermination.getRequestElements().size() > 0) {
      for (String item : dtm.getRequestElements()) {
        dtm.getRequestElements().add(item);
      }
    }
    dtm.setRequestNodeTriggerType(
        getRequestNodeTriggerType(commonDetermination.getGetExecutingDataStatus()));
    EnumSet<BETriggerTimePointType> enumSet = EnumSet.noneOf(BETriggerTimePointType.class);
    enumSet.add(type);
    dtm.setTriggerTimePointType(enumSet);
    return dtm;
  }

  public static CommonValidation convertToCommonValidation(Validation validation,
      BETriggerTimePointType type) {
    BizCommonValdation cValidation = new BizCommonValdation();
    convertToCommonOperation(cValidation, validation);
    cValidation.setParameterCollection(validation.getParameterCollection());
    if (validation.getRequestElements().size() > 0) {
      for (String item : validation.getRequestElements()) {
        cValidation.getRequestElements().add(item);
      }
    }
    EnumSet<RequestNodeTriggerType> triggerTypes = validation.getValidationTriggerPoints()
        .get(type);
    cValidation.setGetExecutingDataStatus(getExecutingDataStatus(triggerTypes));

    if (validation.getRequestChildElements() != null
        && validation.getRequestChildElements().size() > 0) {
      for (Entry<String, ValElementCollection> item : validation.getRequestChildElements()
          .entrySet()) {
        com.inspur.edp.cef.designtime.api.collection.ValElementCollection collection =
            new com.inspur.edp.cef.designtime.api.collection.ValElementCollection();
        if (item.getValue() != null) {
          for (String s : item.getValue()) {
            collection.add(s);
          }
        }
        cValidation.getRequestChildElements().put(item.getKey(), collection);
      }
    }
    return cValidation;
  }

  /**
   * 触发时机转换
   *
   * @param enumSet
   * @return
   */
  private static EnumSet<ExecutingDataStatus> getExecutingDataStatus(
      EnumSet<RequestNodeTriggerType> enumSet) {
    EnumSet<ExecutingDataStatus> set = EnumSet.noneOf(ExecutingDataStatus.class);
    boolean isadded = enumSet.contains(RequestNodeTriggerType.Created);
    if (isadded) {
      set.add(ExecutingDataStatus.added);
    }
    boolean isModify = enumSet.contains(RequestNodeTriggerType.Updated);
    if (isModify) {
      set.add(ExecutingDataStatus.Modify);
    }
    boolean isDeleted = enumSet.contains(RequestNodeTriggerType.Deleted);
    if (isDeleted) {
      set.add(ExecutingDataStatus.Deleted);
    }
    return set;
  }

  //老联动默认加上所有时机
  private static EnumSet<ExecutingDataStatus> getAllChildExecutingDataStatus() {
    EnumSet<ExecutingDataStatus> set = EnumSet.noneOf(ExecutingDataStatus.class);
    set.add(ExecutingDataStatus.added);
    set.add(ExecutingDataStatus.Modify);
    set.add(ExecutingDataStatus.Deleted);
    return set;
  }

  private static EnumSet<RequestNodeTriggerType> getRequestNodeTriggerType(
      EnumSet<ExecutingDataStatus> enumSet) {
    EnumSet<RequestNodeTriggerType> set = EnumSet.noneOf(RequestNodeTriggerType.class);
    boolean isadded = enumSet.contains(ExecutingDataStatus.added);
    if (isadded) {
      set.add(RequestNodeTriggerType.Created);
    }
    boolean isModify = enumSet.contains(ExecutingDataStatus.Modify);
    if (isModify) {
      set.add(RequestNodeTriggerType.Updated);
    }
    boolean isDeleted = enumSet.contains(ExecutingDataStatus.Deleted);
    if (isDeleted) {
      set.add(RequestNodeTriggerType.Deleted);
    }
    return set;
  }

  /**
   * commonOperation基类属性转换
   *
   * @param commonOp
   * @param bizOp
   */
  private static void convertToCommonOperation(CommonOperation commonOp, BizOperation bizOp) {
    commonOp.setID(bizOp.getID());
    commonOp.setCode(bizOp.getCode());
    commonOp.setName(bizOp.getName());
    commonOp.setDescription(bizOp.getDescription());
    commonOp.setComponentId(bizOp.getComponentId());
    commonOp.setComponentName(bizOp.getComponentName());
    commonOp.setComponentPkgName(bizOp.getComponentPkgName());
  }

  private static BETriggerTimePointType convert2TriggerTimePointType(String value,
      CommonTriggerPointType trigger) {
    if (value == null) {
      return BETriggerTimePointType.None;
    }
    switch (value) {
      case CefNames.DtmAfterCreate:
        return BETriggerTimePointType.RetrieveDefault;
      case CefNames.DtmAfterModify:
      case BizEntityJsonConst.ValueChangedDtm:
      case BizEntityJsonConst.ValueChangedVal:
      case BizEntityJsonConst.ComputationDtm:
      case CefNames.ValAfterModify:
        return BETriggerTimePointType.AfterModify;
      case CefNames.DtmBeforeSave:
      case CefNames.ValBeforeSave:
        return BETriggerTimePointType.BeforeCheck;
      case BizEntityJsonConst.B4QueryDtm:
        return BETriggerTimePointType.BeforeQuery;
      case BizEntityJsonConst.AftQueryDtm:
        return BETriggerTimePointType.AfterQuery;
      case BizEntityJsonConst.DtmCancel:
        return BETriggerTimePointType.Cancel;
      case BizEntityJsonConst.B4RetrieveDtm:
        return BETriggerTimePointType.BeforeRetrieve;
      case BizEntityJsonConst.AftLoadingDtm:
        return BETriggerTimePointType.AfterLoading;
      case BizEntityJsonConst.ItemDeletingDtm:
      case BizEntityJsonConst.ItemDeletingVal: {
        switch (trigger) {
          case AfterModify:
            return BETriggerTimePointType.AfterModify;
          case BeforeSave:
            return BETriggerTimePointType.BeforeCheck;
          default:
            return BETriggerTimePointType.None;
        }
      }
      case BizEntityJsonConst.ValidationAfterSave:
        return BETriggerTimePointType.AfterSave;
      default:
        throw new IllegalArgumentException(value);
    }
  }
  // endregion
}
